#include "Ai-Kun.h"
#include "SpellManager.h"

//////////////////////////
#ifndef CSTRING_	//2/18/08
#define CSTRING_
#include<cstring>	// for string compare
#endif							
//////////////////////////


Player::Player(std::string filename, float x, float y, PLAYERID playerID, bool h)
{
	humanOpponent = h;
	Health = 100;			// Holds the life of the player/Ai or .... ya its 100 so shut up.. noob...
// Zach doesn't need this thing anymore...... maybe	BranchNum = 0;			// Keep track of the Branch they are on, this should only be  1 - 4 ( 0 = no BranchNum)
	BranchLoc = 0;			// Keeps track of where they are on the branch, IE 0 - 29 ( 0 = no branch location)
	Dead = false;			// no you don't start dead Jim!!
	TrunkLoc = 0;			// Its the start so you start at the start... its smart like that
	
	pID = playerID;

//	human = h;

	onBranch = false;
	atFront = false;
	frontCtr = 0;
	spellTriggered = false;
	movingForward = false;
	setCastSpell(false);

	dx = 0;
	dy = 0;
	halfTileWidth = 32.0f;
	//dxp2 = 0;
	//dyp2 = 0;

	spellAlive = false;
	
	//added 2/13/08
	onBranch = false;
	atFront = false;
	spellTriggered = false;
	movingForward = false;
	frontCtr = 0;

	//load texture for potrait and lifebar
	//if we wanted to have different lifebars, would pass another filename, or perhaps move these to separate functions
	HR(D3DXCreateTextureFromFile(gd3dDevice, filename.c_str(), &mPlayerPortrait));
	mPlayerPortraitPos = D3DXVECTOR3(x, y, 0.0f);
	mPlayerPotraitCenter = D3DXVECTOR3(halfTileWidth, 64.0f, 0.0f);

	//lifebar shouldn't be hard coded, but for simplicity it is, only variable added was for position
	HR(D3DXCreateTextureFromFile(gd3dDevice, "LifeBar.png", &mLifeBar));
	mLifeBarCenter = D3DXVECTOR3(256.0f, halfTileWidth, 0.0f);
	
	//mLifeBarPos = lifeBarPos;
	
}

Player::~Player()
{
/*
	player.setBranchIteratorBegin();
	player.setTrunkIteratorBegin();

	while(player.getTrunkIteratorEndIf())
	{
		if(player.getTrunkIteratorIsNodeTile())
			player.setTrunkIteratorFree();

		player.increaseTrunkIterator();
	}

	while(player.getBranchIteratorEndIf())
	{
		player.setBranchTilesPopBack();
		player.incrementBranchIterator();
	}
*/
	// Not much going on here....
	ReleaseCOM(mPlayerPortrait);
	ReleaseCOM(mLifeBar);
}

void Player::update()
{
	if ( Dead)
	{
		// End game you lose?
	}
}

void Player::readerSetUp()
{
	int nodeNbr = 0;

	//temp for now, need to add this functionality to the reader class or editor, shdn't be set how it is now
	SpellType temp = TrunkTile;

	//char fileName[24] = "test.txt";// spell map is here
	//fileName[24] = "sm_1.txt";// spell map is here
	strcpy(fileName, "Test.txt");


	File file;
	
	fileReader *reader = new fileReader();
	
	file = reader->readFile(fileName);
	
	reader->setSpell(file, fileName, 24);

	// Pushes the Trunk onto the list to be drawn
	for(int i = 0; i < 20; i++)
	{
		//we are at a node tile
		if(i%5 == 4)
		{
			//setting spell type
			switch(i)
			{
				case 4:
					temp = Fire;
					break;
				case 9:
					temp = Water;
					break;
					
				case 14:
					temp = Wind;
					break;
				case 19:
					temp = Earth;
					break;
				default:
					temp = TrunkTile;
					break;
			}

			Tiles tile((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, NodeTile, temp, false, nodeNbr);
			trunkTiles.push_back(tile);
		
			//create spell tree for node
			createSpellTree(reader, nodeNbr, temp);
			
			nodeNbr++;

		}
		else
		{

			//spell type = trunk, tileType = Trunk_Branch
			Tiles tile((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, Trunk_Branch, TrunkTile);
			trunkTiles.push_back(tile);


		}

	}

	//set cursor starting position
//	gameCursorPosition = D3DXVECTOR3(trunkTiles.front().getX(), trunkTiles.front().getY(), 0.0f);
	// I need to add this to the player class... (Zach)


	//set iterator
	trunkIterator = trunkTiles.begin();
	trunkIterator++;

	cursorIter = trunkTiles.begin();

	//free reader
	delete reader;
}



void Player::createSpellTree(fileReader *reader, int nodeNbr, SpellType spell)
{


	//aligning rank one spells up with proper node on trunk
	float dx1[4];
	float dy1[4];

	//align rank 2 with rank 1
	float dx;
	float dy;
	
	//align rank 3 with rank 2
	float dx2;
	float dy2;  
	bool front = false;

		//assigning translation values
	dx1[0] = (reader->TrunkP.mPointX[4]);
	dy1[0] = reader->TrunkP.mPointY[4];

	dx1[1] = (reader->TrunkP.mPointX[9]);
	dy1[1] = reader->TrunkP.mPointY[9];

	dx1[2] = (reader->TrunkP.mPointX[14]);
	dy1[2] = reader->TrunkP.mPointY[14];

	dx1[3] = (reader->TrunkP.mPointX[19]);
	dy1[3] = reader->TrunkP.mPointY[19];



	dx = (reader->SpellHolder[nodeNbr][0].mPointX[9] + dx1[nodeNbr]);
	dy = (reader->SpellHolder[nodeNbr][0].mPointY[9] + dy1[nodeNbr]);
	
	dx2 = (reader->SpellHolder[nodeNbr][1].mPointX[9] + dx);
	dy2 = (reader->SpellHolder[nodeNbr][1].mPointY[9] + dy);


	//Pushes Rank 1 onto the list to be drawn
	for(int i = 0; i < 10; i++)
	{	
		if(i == 0)
			front = true;
		else
			front = false;

		if(i == 9)
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, SPELLTILE, spell, false, nodeNbr, front, 1, true, reader->getSpellHold(nodeNbr, 0).Number );
			branchTiles.push_back(branchTile);
		}
		else
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 1);
			branchTiles.push_back(branchTile);
		}

	}
	
	// Pushes Rank 2 onto the list to be drawn
	for(int i = 0; i < 10; i++)
	{	
		front = false;

	

		//added 10/21/07 @ 6:07
		if(i == 9)
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 2, true, reader->SpellHolder[nodeNbr][1].Number);
			branchTiles.push_back(branchTile);
		}
		else
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 2);
			branchTiles.push_back(branchTile);
		}
	}

	// Pushed Rank 3 onto the list to be drawn
	for(int i = 0; i < 10; i++)
	{		
		//mistake: this is the 3rd rank of the nodes spell tree, front shd be false, only needs to be true for first
		//rank, first tile

		front = false;
		

		//added 10/21/07 @ 6:07
		if(i == 9)
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 3, true, reader->SpellHolder[nodeNbr][2].Number);
			branchTiles.push_back(branchTile);
		}
		else
		{
			Branch branchTile((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 3);
			branchTiles.push_back(branchTile);
		}
	}
}


//AI::AI(void)
//{
//	Health = 90; // Set to 90 to test drawing area
//	TargetSpell = 10; // No the target hasn't been reached.
//	Target = false; // no it hasn't reached the spell yet
//
//	TargetEnd = 4; // I am seting this to the First node 
//
//	Butten = false;
//	Branch =  false;
//
//}


// Now Time for AI KON!!!!

AI::AI(std::string filename, float x, float y, PLAYERID playerID, bool h):Player(filename, x, y, playerID, h)
{
	Health = 100;			// Holds the life of the player/Ai or .... ya its 100 so shut up.. noob...
// Zach doesn't need this thing anymore...... maybe	BranchNum = 0;			// Keep track of the Branch they are on, this should only be  1 - 4 ( 0 = no BranchNum)
	BranchLoc = 0;			// Keeps track of where they are on the branch, IE 0 - 29 ( 0 = no branch location)
	Dead = false;			// no you don't start dead Jim!!
	TrunkLoc = 0;			// It is the start so you start at the start... its smart like that
	
	//pID = playerID;
	// added 01/14/08 Zach
	// Used for migrating movement into the player class
	onBranch = false;
	atFront = false;
	frontCtr = 0;
	spellTriggered = false;
	movingForward = false;
	setCastSpell(false);

	dx = 0;
	dy = 0;
	halfTileWidth = 32.0f;
	//dxp2 = 0;
	//dyp2 = 0;

	spellAlive = false;

	//load texture for potrait and lifebar
	//if we wanted to have different lifebars, would pass another filename, or perhaps move these to separate functions
	HR(D3DXCreateTextureFromFile(gd3dDevice, filename.c_str(), &mPlayerPortrait));
	mPlayerPortraitPos = D3DXVECTOR3(x, y, 0.0f);
	mPlayerPotraitCenter = D3DXVECTOR3(halfTileWidth, 64.0f, 0.0f);

	//lifebar shouldn't be hard coded, but for simplicity it is, only variable added was for position
	HR(D3DXCreateTextureFromFile(gd3dDevice, "LifeBar.png", &mLifeBar));
	mLifeBarCenter = D3DXVECTOR3(256.0f, halfTileWidth, 0.0f);
	
	//mLifeBarPos = lifeBarPos;


	//Health = 90; // Set to 90 to test drawing area
	TargetSpell = 30; // No the target hasn't been reached.
	Target = false; // no it hasn't reached the spell yet

	TargetEnd = 4; // I am seting this to the First node 

	Butten = false;
	Branch =  false;

}

AI::~AI()
{
	// nothing cool happening here.....
}

void AI::update()
{

		if ( TrunkLoc = TargetEnd || Target)
		{
			getNewTarget();
		}
		else
		{
		//	updateMovement(ai);
		}
}

void AI::getNewTarget()
{
	int Number = 0; // This hold the highest desier and stuff
	int SpellNum = 0; // This hold the spell you are going after
	int SpellNode = 0; // Holds the target node

	for (int i = 0; i < 4; i++)
	{
		for (int m = 0; m < 3; m++)
		{
			if ( Number <  ( SpellHolder[i][m].Power + Health + (TrunkLoc - ((i+1) * 5) - ( m * 10))) )//;
			{
				Number = ( SpellHolder[i][m].Power + Health + (TrunkLoc - ((i+1) * 5) - ( m * 10)));
				SpellNum = (((m+1) * 10)); // equal to the spell rank, then we multiple by 10 to give the number of tiles.
				SpellNode = (i + 1) * 5;
				spellID = SpellHolder[i][m].ID;
			}
		}
	}

	TargetSpell = 30;//SpellNum;//
	TargetEnd = 4;//SpellNode;//
	Target = false;
	//MessageBox(gd3dApp->getMainWindowHandle(), "Test", "Error", 0);
}

bool AI::updateMovement(Player *player)
{
	if ( (1 + (rand()%300)) == 1 )
	{

		if ( Branch) // if true we are moving on the branch!
		{
			branchIter = branchTiles.begin();

			for ( int i = 0; i < ((BranchLoc - 1)); i++)
			{
				branchIter++;
			}

			dxt = branchIter->getX();
			dyt = branchIter->getY();

			if( BranchLoc < TargetSpell)
			{
				branchIter++;
				
				dxt2 = branchIter->getX();
				dyt2 = branchIter->getY();
				
				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
				
				++BranchLoc; //ai.setBranchLoc((ai.getBranchLoc() + 1));
				return true;
			}

			else if ( BranchLoc > TargetSpell )
			{
				if (BranchLoc == 1)
				{
					cursorIter = trunkTiles.begin();

					for ( int i = 0; i < (TrunkLoc); i++)
					{
						cursorIter++;
					}

					dxt = branchIter->getX();
					dyt = branchIter->getY();
					// Move it to trunk and re-target Ai			

					dxt2 = cursorIter->getX();
					dyt2 = cursorIter->getY();

					//new translation value to add
					dx += dxt - dxt2;
					dy += dyt - dyt2;					
					BranchLoc--; //ai.setBranchLoc((ai.getBranchLoc() - 1));
				}

				else
				{

				branchIter--;

				dxt2 = branchIter->getX();
				dyt2 = branchIter->getY();

				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
							
				--BranchLoc; //ai.setBranchLoc((ai.getBranchLoc() - 1));

				}
				return true;
			}

			else
			{
				if ( BranchLoc > 0)
				{
					TargetSpell = 0;
				}
				else
				{

	

					Branch = false; //ai.setBranchFalse(); // Changes on branch to false

					getNewTarget(); // Sets the new target

					/**************************************/
					// Damage is done here!
					/**************************************/
					//set cooldown to true for that node; rank and nodeID has been recorded, they activated spell
					cursorIter->getNode()->setCoolDown(true);

					//change the branch color
					setCoolDown(nodeID, rank, true);
					
					//set spell to fire
					SpellManager::instance()->addSpell(spellID, player);

					//reset trigger for spell
					spellTriggered = false;


					//playanime(1,1);
				}
				return true;
			}
		}

		else // We are moving the node!
		{

			cursorIter = trunkTiles.begin();

			for ( int i = 0; i < (TrunkLoc - 1); i++)
			{
				cursorIter++;
			}

			dxt = cursorIter->getX();
			dyt = cursorIter->getY();

			if( TrunkLoc < TargetEnd)
			{

				cursorIter++;
				
				dxt2 = cursorIter->getX();
				dyt2 = cursorIter->getY();
				
				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
			
				
				TrunkLoc++; //ai.setTrunkLoc((ai.getTrunkLoc() + 1));
				return true;

			}

			else if ( TrunkLoc > TargetEnd)
			{

				cursorIter--;

				dxt2 = cursorIter->getX();
				dyt2 = cursorIter->getY();

				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
											
				BranchLoc--; //ai.setBranchLoc((ai.getBranchLoc() - 1));
				return true;
			}

			else
			{
				Branch = true; //ai.setBranchTrue();			// sets on branch to true
				return true;
			}
		}	

	//return true;	
	}
	
	else
	{
		return false;
	}
}




bool Player::moveCursor(Button button, Player *player)
{
	//b4 move
	dxt = cursorIter->getX();
	dyt = cursorIter->getY();

	//mGfxStats->setPrev(dxt);

	//check if branch
	if(!onBranch && cursorIter->isNodeTile() && !cursorIter->getNode()->inCoolDown() && getFirstBranchButton(cursorIter->getNode()->getNodeID()) == button)
	{
		//get node nbr
		dxt2 = branchIter->getX();
		dyt2 = branchIter->getY();

		//new translation value to add
		dx += dxt - dxt2;
		dy += dyt - dyt2;
		
		onBranch = true;
		atFront = true;
		return true;
	}
	else
	{
		//getting next key button press
		//cursorIter++;

		if(onBranch)
		{
			//check if trying to go back on trunk
		
			if(cursorIter->getButtonPress() == button && branchIter->getFront())
			{
				dxt = branchIter->getX();
				dyt = branchIter->getY();

				//gameCursorPosition = D3DXVECTOR3(cursorIter->getX(), cursorIter->getY(), 0.0f);
				dxt2 = cursorIter->getX();
				dyt2 = cursorIter->getY();

				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
				//mGfxStats->setNext(dx);
				//reset delay

				onBranch = false;
			
				//trigger cool down, spell cast, etc*****************************************************
				//added 10/21/07
				//they triggered a spell, once they hit the node, blast away
				//if(cursorIter->getNode()->inCoolDown())
				if(spellTriggered && !onBranch)
				{
					//set cooldown to true for that node; rank and nodeID has been recorded, they activated spell
					cursorIter->getNode()->setCoolDown(true);

					//change the branch color
					setCoolDown(nodeID, rank, true);
					
					//set spell to fire
					SpellManager::instance()->addSpell(spellID, player);

					//reset trigger for spell
					spellTriggered = false;
				}

				return true;
			}
		
			else
			{
				dxt = branchIter->getX();
				dyt = branchIter->getY();

				//increment branch iter to get next branch button
				branchIter++;
				//mGfxStats->setNext((int)branchIter->getButtonPress());
				if(branchIter->getButtonPress()== button && !endofBranch(cursorIter->getNode()->getNodeID()))
				{
					//added 10/21/07
					movingForward = true;

					//gameCursorPosition = D3DXVECTOR3(branchIter->getX(), branchIter->getY(), 0.0f);
					dxt2 = branchIter->getX();
					dyt2 = branchIter->getY();

					//new translation value to add
					dx += dxt - dxt2;
					dy += dyt - dyt2;
					//mGfxStats->setNext(dx);
					//reset delay
					frontCtr++;
					return true;
				}
				else
				{					
					//move it back twice to check previous button
					branchIter--;

					//check to see if player is currently on spell tile added 10/21/07
					spellTile = branchIter->getIsSpellTile();

					
					if(spellTile  && !spellTriggered && movingForward)
					{
						rank = branchIter->getSpellTile()->getRank();
						spellID = (branchIter->getSpellTile()->getSpellID());
						nodeID = branchIter->getNodeID();
						spellTriggered = true;
					}

					branchIter--;

					if(branchIter->getButtonPress() == button && !endofBranch(cursorIter->getNode()->getNodeID()))
					{
						//added 10/21/07

						
						//reset moving forward added 10/21/07
						movingForward = false;

						//set cursor position
						//gameCursorPosition = D3DXVECTOR3(branchIter->getX(), branchIter->getY(), 0.0f);
						dxt2 = branchIter->getX();
						dyt2 = branchIter->getY();

						//new translation value to add
						dx += dxt - dxt2;
						dy += dyt - dyt2;
						//mGfxStats->setNext(dx);
						//reset delay
						frontCtr--;
						return true;
					}
					else
						//move cursor back to current position
						branchIter++;
				}
			}
		}//end if(onBranch)
		else
		{
			cursorIter++;
			//mGfxStats->setNext((int)cursorIter->getButtonPress());
			if(cursorIter->getButtonPress() == button)
			{

				//gameCursorPosition = D3DXVECTOR3(cursorIter->getX(), cursorIter->getY(), 0.0f);
				dxt2 = cursorIter->getX();
				dyt2 = cursorIter->getY();

				//new translation value to add
				dx += dxt - dxt2;
				dy += dyt - dyt2;
				//mGfxStats->setNext(dx);
				//reset delay

				return true;
			}
			else
			{
				//move it back twice to check previous button
				cursorIter--;
				cursorIter--;

				if(cursorIter->getButtonPress() == button)
				{
					//set cursor position
					//gameCursorPosition = D3DXVECTOR3(cursorIter->getX(), cursorIter->getY(), 0.0f);
					
					dxt2 = cursorIter->getX();
					dyt2 = cursorIter->getY();
					
					//new translation value to add
					dx += dxt - dxt2;
					dy += dyt - dyt2;
					//mGfxStats->setNext(dx);
					//reset delay

					return true;
				}
				else
					//move cursor back to current position
					cursorIter++;
			}
		}
	}
}

int Player::getFirstBranchButton(int nodeID)
{
	int button;
	int node;

	branchIter = branchTiles.begin();

	//added the second && part 10/21/07
	while(branchIter->getNodeID() != nodeID  && branchIter != branchTiles.end())
	{
		branchIter++;
	}

	node = branchIter->getNodeID();
	button = branchIter->getButtonPress();

	//mGfxStats->setPrev(branchIter->getButtonPress());

	return branchIter->getButtonPress();

}
bool Player::endofBranch(int id)
{
	if(branchIter->getNodeID() != id)
		return true;

	return false;
}
void Player::setCoolDown(int nodeID, int rank, bool coolDownState)
{
	std::list<Branch>::iterator i = branchTiles.begin();
	while(i != branchTiles.end())
	{
		if(i->getNodeID() == nodeID && i->getRank() <= rank)
		{
			i->setCoolDown(coolDownState);
		}

		i++;
	}
}

//update cooldowns
void Player::updateCoolDowns(float dt)
{
	//make an iterator to check the node tiles
	std::list<Tiles>::iterator i = trunkTiles.begin();

	//static float time = 0.0f; 
	
	//increment time
	//time += dt;

	//update cool down times
	while(i != trunkTiles.end())
	{
		//update cool down time for each node in cool down
		if(i->isNodeTile())
		{
			if(i->getNode()->inCoolDown())
			{
				i->getNode()->updateCoolDownTime(dt);
			}
		}

		i++;
	}

	//loop through updated nodes set cool down to false for any that have cool down time > 15
	i = trunkTiles.begin();

	while(i != trunkTiles.end())
	{
		if(i->isNodeTile())
		{
			if(i->getNode()->inCoolDown())
			{
				if(i->getNode()->getCoolDownTime() >= 15.0f)
				{
					//set cool down to false for the node
					i->getNode()->setCoolDown(false);

					//update branch tiles, start at highest rank (kind of bad, but oh well)
					setCoolDown(i->getNode()->getNodeID(), 3, false);
				}
			}
		}

		i++;
	}


}